package com.droidski.taskdb.web;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.mortbay.jetty.Request;
import org.mortbay.jetty.handler.AbstractHandler;

public class BaseRestHandler extends AbstractHandler {

	List<Method> _annotatedMethods;
	
	public BaseRestHandler() {
		_init();
	}
	
	@Override
	public final void handle(String target, HttpServletRequest req,
			HttpServletResponse res, int dispatch) throws IOException,
			ServletException {
		
		Method m = getMethod(req);
		if ( m == null ) {
			res.sendError(404);
		} else {
			try {
				m.invoke(this, req, res);
				((Request) req).setHandled(true);
			} catch (Exception e) {
				e.printStackTrace();
				throw new ServletException(e);
			}
		}
		
	}
	
	private final Method getMethod(HttpServletRequest request) {

		for ( Method m : _annotatedMethods ) {
			Rest cmd = m.getAnnotation(Rest.class);
			String regexStr = cmd.regex();
			if ( request.getRequestURI().trim().matches(regexStr)) {
//				Main.out("regex=" + regexStr + " : HIT");
				return m;
			} else {
//				Main.out("regex=" + regexStr + " : MISS");
			}
		}
		return null;
	}
	
	public static StringBuffer debugRequest(HttpServletRequest request) {
		StringBuffer sb = new StringBuffer();
		sb.append("\nrequest:");
		sb.append("\nauthtype             : " + request.getAuthType());
		sb.append("\ngetCharacterEncoding : " + request.getCharacterEncoding());
		sb.append("\ngetContentLength     : " + request.getContentLength());
		sb.append("\ngetContentType       : " + request.getContentType());
		sb.append("\ngetContextPath       : " + request.getContextPath());
		sb.append("\nmethod               : " + request.getMethod());
		sb.append("\npathInfo             : " + request.getPathInfo());
		sb.append("\npathTranslated       : " + request.getPathTranslated());
		sb.append("\nrequestURL           : " + request.getRequestURL().toString());
		sb.append("\nrequestURI           : " + request.getRequestURI());
		sb.append("\nprotocol             : " + request.getProtocol());
		sb.append("\nqueryString          : " + request.getQueryString());
		sb.append("\n");
		return sb;
	}
	
	private final void _init() {

		List<Method> results = new ArrayList<Method>();
		Method[] methods = getClass().getMethods();
		for ( Method method : methods ) {
			Rest cmd = (Rest)method.getAnnotation(Rest.class);
			if ( cmd != null ) {
				results.add(method);
			}
		}
		_annotatedMethods = results;
	
	}

	public enum OutputFormat { JSON, XML, PLAINTEXT };
	
	public static OutputFormat getOutputFormat(HttpServletRequest request) {
		String oType = request.getHeader("format");
		try {
			return OutputFormat.valueOf(oType.toUpperCase());
		} catch (Exception e) {
			return OutputFormat.JSON;
		}
	}
	
}
